package drds.plus.sql_process.type.impl;

import drds.plus.common.model.RowValues;
import drds.plus.sql_process.type.*;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;

public class StringType extends AbstractType<String> {

    private final Calculator calculator = new AbstractCalculator() {

        public BigDecimal convertToBigDecimal(Object v) {
            return BigDecimalType.convert(v);
        }

        public Object doAdd(Object v1, Object v2) {
            BigDecimal d1 = convertToBigDecimal(v1);
            BigDecimal d2 = convertToBigDecimal(v2);

            return BigDecimalType.getCalculator().add(d1, d2);
        }

        public Object doSub(Object v1, Object v2) {
            BigDecimal d1 = convertToBigDecimal(v1);
            BigDecimal d2 = convertToBigDecimal(v2);

            return BigDecimalType.getCalculator().sub(d1, d2);
        }


        public Object doMultiply(Object v1, Object v2) {
            BigDecimal d1 = convertToBigDecimal(v1);
            BigDecimal d2 = convertToBigDecimal(v2);

            return BigDecimalType.getCalculator().multiply(d1, d2);
        }

        public Object doDivide(Object v1, Object v2) {
            BigDecimal d1 = convertToBigDecimal(v1);
            BigDecimal d2 = convertToBigDecimal(v2);

            return BigDecimalType.getCalculator().divide(d1, d2);
        }

        public Object doMod(Object v1, Object v2) {
            BigDecimal d1 = convertToBigDecimal(v1);
            BigDecimal d2 = convertToBigDecimal(v2);

            return BigDecimalType.getCalculator().mod(d1, d2);
        }


    };

    public ResultGetter getResultGetter() {
        return new ResultGetter() {

            public Object get(ResultSet resultSet, int index) throws SQLException {
                return resultSet.getString(index);
            }

            public Object get(RowValues rowValues, int index) {
                Object val = rowValues.getObject(index);
                return convert(val);
            }
        };
    }

    public int encode(Object value, byte[] bytes, int offset) {
        return Encoder.encodeString(this.convert(value), bytes, offset);
    }

    public int getLength(Object value) {
        if (value == null) {
            return 1;
        } else {
            return Encoder.calculateEncodedLength(this.convert(value));
        }
    }

    public DecodeResult decode(byte[] bytes, int offset) {
        String[] vs = new String[1];
        int lenght = Decoder.decodeStringObject(bytes, offset, vs);
        return new DecodeResult(vs[0], lenght);
    }

    public String incr(Object value) {
        String c = convert(value);
        StringBuilder newStr = new StringBuilder(c);
        newStr.setCharAt(newStr.length() - 1, (char) (newStr.charAt(newStr.length() - 1) + 1));
        return newStr.toString();
    }

    public String decr(Object value) {
        String c = convert(value);
        StringBuilder newStr = new StringBuilder(c);
        newStr.setCharAt(newStr.length() - 1, (char) (newStr.charAt(newStr.length() - 1) - 1));
        return newStr.toString();
    }

    public String getMaxValue() {
        return new String(new char[]{Character.MAX_VALUE});
    }

    public String getMinValue() {
        return null; // 返回null值
    }

    public int compare(Object o1, Object o2) {
        if (o1 == o2) {
            return 0;
        }
        if (o1 == null) {
            return -1;
        }

        if (o2 == null) {
            return 1;
        }

        String no1 = convert(o1);
        String no2 = convert(o2);

        /**
         * mysql 默认不区分大小写，这里可能是个坑
         */
        return no1.compareToIgnoreCase(no2);
    }

    public Calculator getCalculator() {
        return calculator;
    }

    public int getSqlType() {
        return java.sql.Types.VARCHAR;
    }
}
